package handlers

import (
	"context"
	"fmt"
	"net/http"
	"time"

	"enzyme-backend/core/models"
	"enzyme-backend/core/services"
	"enzyme-backend/core/utils"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

// Handler HTTP处理器
type Handler struct{}

// NewHandler 创建新的处理器实例
func NewHandler() *Handler {
	return &Handler{}
}

// Register 用户注册
func (h *Handler) Register(c *gin.Context) {
	var req RegisterRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		utils.GlobalLogger.Error("Register 1: %v", err)
		c.JSON(http.StatusBadRequest, gin.H{
			"error": "请求参数错误: " + err.Error(),
		})
		return
	}

	if err := services.GlobalUser.Register(c, req.Email, req.Password, req.VerifyCode, req.Fingerprint); err != nil {
		utils.GlobalLogger.Error("Register 2: %v", err)
		c.JSON(http.StatusBadRequest, gin.H{
			"error": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{})
}

// Login 用户登录
func (h *Handler) Login(c *gin.Context) {
	var req LoginRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"error": "请求参数错误: " + err.Error(),
		})
		return
	}

	token, err := services.GlobalUser.Login(c, req.Email, req.Password, req.Fingerprint)
	if err != nil {
		c.JSON(http.StatusUnauthorized, gin.H{
			"error": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"token": token,
	})
}

// Verify 验证token
func (h *Handler) Verify(c *gin.Context) {
	token := c.GetString("token")
	if token == "" {
		c.JSON(http.StatusUnauthorized, gin.H{
			"error": "token不能为空",
		})
		return
	}

	if err := services.GlobalUser.VerifyToken(c, token); err != nil {
		c.JSON(http.StatusUnauthorized, gin.H{
			"error": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{})
}

// SendCode 发送验证码
func (h *Handler) SendCode(c *gin.Context) {
	var req SendCodeRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"error": "请求参数错误: " + err.Error(),
		})
		return
	}

	if err := services.GlobalUser.SendVerifyCode(c, req.Email); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"error": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{})
}

// RemakePassword 重置密码
func (h *Handler) RemakePassword(c *gin.Context) {
	var req RemakePasswordRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"error": "请求参数错误: " + err.Error(),
		})
		return
	}

	if err := services.GlobalUser.RemakePassword(c, req.Email, req.VerifyCode, req.NewPassword); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"error": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{})
}

// QuerySubscription 查询订阅状态
func (h *Handler) QuerySubscription(c *gin.Context) {
	token := c.GetString("token")
	if token == "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"error": "token不能为空",
		})
		return
	}

	user, err := services.GlobalUser.GetUserByToken(c, token)
	if err != nil && err != gorm.ErrRecordNotFound {
		utils.GlobalLogger.Error("QuerySubscription: %v", err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"error": err.Error(),
		})
		return
	}
	if user == nil {
		device, err := services.GlobalUser.GetDeviceByToken(c, token)
		if err != nil {
			utils.GlobalLogger.Error("QuerySubscription: %v", err)
			c.JSON(http.StatusInternalServerError, gin.H{
				"error": err.Error(),
			})
			return
		}
		if device == nil {
			c.JSON(http.StatusNotFound, gin.H{
				"error": "用户不存在",
			})
			return
		}
		c.JSON(http.StatusOK, gin.H{
			"expired_at":   device.ExpiredAt,
			"usage_amount": device.UsageAmount,
			"total_amount": device.GetTotalAmount(),
		})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"expired_at":   user.ExpiredAt,
		"usage_amount": user.UsageAmount,
		"total_amount": user.GetTotalAmount(),
	})
}

// GetOrderTypes 获取订单类型列表
func (h *Handler) GetOrderTypes(c *gin.Context) {
	orderTypes := services.GlobalOrder.GetOrderTypes(c)
	orderTypesList := make([]map[string]any, 0, len(orderTypes))
	for orderKey, orderType := range orderTypes {
		orderTypesList = append(orderTypesList, map[string]any{
			"name":       orderType.Name,
			"price":      orderType.Price,
			"order_type": orderKey,
		})
	}
	c.JSON(http.StatusOK, gin.H{
		"order_types": orderTypesList,
	})
}

// CreateAlipayOrder 创建支付宝订单
func (h *Handler) CreateAlipayOrder(c *gin.Context) {
	var req CreateAlipayOrderRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		utils.GlobalLogger.Error("CreateAlipayOrder: %v", err)
		c.JSON(http.StatusBadRequest, gin.H{
			"error": "请求参数错误: " + err.Error(),
		})
		return
	}
	token := c.Value("token").(string)

	// 创建订单交易记录
	transaction, err := services.GlobalOrder.CreateOrderTransaction(c, token, req.OrderType)
	if err != nil {
		utils.GlobalLogger.Error("CreateAlipayOrder 2: %v", err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"error": err.Error(),
		})
		return
	}
	utils.GlobalLogger.Info("CreateAlipayOrder 1: %v", transaction)

	// 创建支付宝支付链接
	subject := fmt.Sprintf("Enzyme VPN - %s", req.OrderType)
	payURL, err := services.GlobalAlipay.CreatePagePay(c, transaction.OutTradeNo, subject, transaction.Amount)
	if err != nil {
		utils.GlobalLogger.Error("CreateAlipayOrder 3: %v", err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"error": "创建支付链接失败: " + err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"payment_url": payURL,
	})
}

// AlipaySuccess 支付宝支付成功回调
func (h *Handler) AlipaySuccess(c *gin.Context) {
	// 获取支付宝回调参数
	outTradeNo := c.Query("out_trade_no")
	paymentID := c.Query("trade_no")

	if outTradeNo == "" || paymentID == "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"error": "缺少必要参数",
		})
		return
	}

	// 处理支付成功
	if err := services.GlobalOrder.ProcessPaymentSuccess(c, outTradeNo, paymentID); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"error": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message": "支付成功",
	})
}

// AlipayNotify 支付宝异步通知
func (h *Handler) AlipayNotify(c *gin.Context) {
	// 获取支付宝异步通知参数
	notifyData := make(map[string]string)
	c.Request.ParseForm()
	for key, values := range c.Request.Form {
		if len(values) > 0 {
			notifyData[key] = values[0]
		}
	}

	// 验证异步通知签名
	if !services.GlobalAlipay.VerifyNotify(notifyData) {
		c.String(http.StatusBadRequest, "fail")
		return
	}

	// 解析通知结果
	notifyResult := services.GlobalAlipay.ParseNotifyResult(notifyData)

	// 只处理支付成功的通知
	if !notifyResult.IsTradeSuccess() {
		c.String(http.StatusOK, "success")
		return
	}

	// 处理支付成功
	if err := services.GlobalOrder.ProcessPaymentSuccess(c, notifyResult.OutTradeNo, notifyResult.TradeNo); err != nil {
		c.String(http.StatusInternalServerError, "fail")
		return
	}

	c.String(http.StatusOK, "success")
}

// FetchConfig 获取配置
func (h *Handler) FetchConfig(c *gin.Context) {
	token := c.Value("token").(string)

	var req FetchConfigRequest
	if err := c.ShouldBind(&req); err != nil {
		utils.GlobalLogger.Error("FetchConfig 1: %v", err)
		c.JSON(http.StatusBadRequest, gin.H{
			"error": "请求参数错误: " + err.Error(),
		})
		return
	}

	user, err := services.GlobalUser.GetUserByToken(c, token)
	isVIP := false
	if err == nil && user != nil {
		isVIP = user.IsVIP()
	}

	// 生成YAML配置
	yamlConfig, err := services.GlobalProxy.GenerateYAMLConfig(req.CountryCode, isVIP)
	if err != nil {
		utils.GlobalLogger.Error("FetchConfig 2: %v", err)
		c.JSON(http.StatusBadRequest, gin.H{
			"error": err.Error(),
		})
		return
	}

	// 设置响应头为YAML
	c.Header("Content-Type", "text/yaml")
	c.String(http.StatusOK, yamlConfig)
}

// CountryList 获取国家列表
func (h *Handler) CountryList(c *gin.Context) {
	countries := services.GlobalProxy.GetAllCountries()
	countries = append(countries, "auto")
	c.JSON(http.StatusOK, gin.H{
		"countries": countries,
	})
}

// ProxyRegister 代理注册
func (h *Handler) ProxyRegister(c *gin.Context) {
	var req ProxyRegisterRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		utils.GlobalLogger.Error("ProxyRegister: %v", err)
		c.JSON(http.StatusBadRequest, gin.H{
			"error": "请求参数错误: " + err.Error(),
		})
		return
	}

	// 创建代理节点信息
	proxyNode := &models.ProxyNode{
		Host:      req.Host,
		Port:      req.Port,
		Password:  req.Password,
		VIP:       req.VIP,
		Country:   req.Country,
		LastHeart: time.Now(),
		Status:    "online",
	}

	// 注册到Redis
	if err := services.GlobalProxy.AddProxy(c, proxyNode); err != nil {
		utils.GlobalLogger.Error("ProxyRegister: %v", err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"error": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{})
}

// ProxyHeartbeat 代理心跳
func (h *Handler) ProxyHeartbeat(c *gin.Context) {
	var req ProxyHeartbeatRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		utils.GlobalLogger.Error("ProxyHeartbeat: %v", err)
		c.JSON(http.StatusBadRequest, gin.H{
			"error": "请求参数错误: " + err.Error(),
		})
		return
	}

	ctx := context.Background()

	// 更新心跳到Redis
	if err := services.GlobalProxy.UpdateProxyHeartbeatToRedis(ctx, req.Key()); err != nil {
		utils.GlobalLogger.Error("ProxyHeartbeat: %v", err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"error": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{})
}
